﻿using System;

namespace DAPNet
{
    public class KasparisLaneDetector : IClickDetector
    {
        private double treshold;

        private DerivativeFilter derivativeFilter;

        private QuadraticMeanFilter quadraticMeanFilter;

        private RecursiveMedianFilter recursiveMedianFilter;


        public KasparisLaneDetector(double treshold, int hpfOrder, int qmfParameter, int rmfParameter)
        {
            this.treshold = treshold;
            this.derivativeFilter = new DerivativeFilter(hpfOrder);
            this.quadraticMeanFilter = new QuadraticMeanFilter(qmfParameter);
            this.recursiveMedianFilter = new RecursiveMedianFilter(rmfParameter);
        }

        internal double Treshold
        {
            get 
            { 
                return treshold; 
            }
            set 
            { 
                treshold = value; 
            }
        }

        internal int HpfOrder
        {
            get 
            { 
                return derivativeFilter.Order; 
            }
            set 
            { 
                derivativeFilter.Order = value; 
            }
        }

        internal int QmfParameter
        {
            get 
            { 
                return quadraticMeanFilter.Parameter; 
            }
            set 
            { 
                quadraticMeanFilter.Parameter = value; 
            }
        }

        internal int RmfParameter
        {
            get 
            { 
                return recursiveMedianFilter.Parameter; 
            }
            set 
            { 
                recursiveMedianFilter.Parameter = value; 
            }
        }

        public ClickDetection Detect(SampleCollection samples)
        {
            SampleCollection w = samples.Clone();
            derivativeFilter.Process(w);
            quadraticMeanFilter.Process(w);

            SampleCollection b = w.Clone();
            recursiveMedianFilter.Process(b);

            ClickDetection detection = new ClickDetection(samples.Count);
            for (int i = 0; i < samples.Count; i++)
            {
                double wValue = w[i].Value;
                double bValue = b[i].Value;
                detection[i] = IsSamplePositive(wValue, bValue);
            }
            return detection;
        }

        private bool IsSamplePositive(double wValue, double bValue)
        {
            double dValue = Math.Abs(wValue - bValue) / bValue;
            return (dValue > treshold);
        }
    }
}
